package com.mars.sso.server.web.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import com.alibaba.fastjson.JSON;
import com.mars.base.common.base.BaseController;
import com.mars.base.common.base.BaseResult;
import com.mars.base.common.contants.SSOConfig;
import com.mars.base.common.utils.CookieUtils;
import com.mars.base.common.utils.IpHelper;
import com.mars.base.common.utils.PasswordUtils;
import com.mars.base.common.utils.RandomUitl;
import com.mars.component.redis.JedisClient;
import com.mars.logger.annotation.Log;
import com.mars.logger.enums.ActionType;
import com.mars.sso.server.web.pojo.SSOUser;
import com.mars.upms.entity.UpmsUser;
import com.mars.upms.rpc.api.UpmsUserService;
import com.mzlion.core.utils.BeanUtils;

@RestController
@RequestMapping(value = "/api/sso")
public class SSOController extends BaseController {

	@Autowired
	private UpmsUserService upmsUserService;

	@Autowired
	private JedisClient jedisClient;

	/**
	 * 登录
	 * 
	 * @param account
	 *            账号
	 * @param password
	 *            密码
	 * @return 用户对象
	 */
	@Log(actionType=ActionType.LOGIN)
	@PostMapping(value = "/login")
	public Object login(String account, String password) {

		UpmsUser upmsUser = this.upmsUserService.getAccount(account);
		if (null == upmsUser) {
			return BaseResult.build(false, "账号不存在");
		} else {
			// 验证密码是否正确
			boolean validatePassword = PasswordUtils.isPasswordValid(upmsUser.getPassword(), password, upmsUser.getSalt());
			if (!validatePassword) {
				return BaseResult.build(false, "密码不正确");
			} else {
				if (upmsUser.getStatus() == 2) {
					return BaseResult.build(false, "账号已被锁定");
				}
				// 清空密码
				upmsUser.setPassword(null);
				// 生成用户会话Token
				String token = RandomUitl.uuid();
				// 设置用户会话Token到Cookie中并设定过期时间
				CookieUtils.setCookie(this.request, this.response, SSOConfig.SSO_TOKEN, token, SSOConfig.TIMEOUT);

				SSOUser user = new SSOUser();
				BeanUtils.copyProperties(upmsUser, user);
				user.setToken(token);

				String redisKey = SSOConfig.REDIS_KEY_SSO_TOKEN_KEY + ":" + token;
				// 将用户信息保存在Redis中
				this.jedisClient.set(redisKey, JSON.toJSONString(user));
				// 设置TOKENG过期时间
				this.jedisClient.expire(redisKey, SSOConfig.TIMEOUT);

				this.upmsUserService.loginRecord(upmsUser.getId(), IpHelper.getIpAddr(request));

				return BaseResult.build(true, "验证成功", user);
			}
		}
	}
	
	/**
	 * 登出
	 * @param token
	 */
	@Log(actionType=ActionType.LOGOUT)
	@GetMapping(value = "/logout/{token}")
	public Object logout(@PathVariable String token) {
		String userStr = this.jedisClient.get(SSOConfig.REDIS_KEY_SSO_TOKEN_KEY + ":" + token);
		SSOUser user = JSON.parseObject(userStr, SSOUser.class);
		if(null != user) {
			this.jedisClient.del(SSOConfig.REDIS_KEY_SSO_TOKEN_KEY + ":" + token);
		}
		return user ;
	}

	/**
	 * 获取当前在线用户
	 * @return
	 */
	@GetMapping("/getOnlineUser")
	public Object getOnlineUser() {
		List<SSOUser> list = new ArrayList<SSOUser>();
		ScanParams scanParams = new ScanParams();
		scanParams.match(SSOConfig.REDIS_KEY_SSO_TOKEN_KEY + ":*");
		ScanResult<String> scan = this.jedisClient.scan("", scanParams);
		List<String> keys = scan.getResult();
		for (String key : keys) {
			String userStr = this.jedisClient.get(key);
			Long expires = this.jedisClient.ttl(key);
			SSOUser user = JSON.parseObject(userStr, SSOUser.class);
			user.setExpires(expires);
			list.add(user);
		}
		return list;
	}
	
	/**
	 * 根据Token获取用户信息
	 * @param token
	 * @return
	 */
	@GetMapping("/getUser/{token}")
	public Object getUser(@PathVariable String token) {
		String user = this.jedisClient.get(SSOConfig.REDIS_KEY_SSO_TOKEN_KEY + ":" + token);
		if(null != user) { //如果Token有效则重设过期时间
			return JSON.parseObject(user, SSOUser.class);
		} else {
			return null ;
		}
	}

	/**
	 * 验证Token有效性，从Redis中获取用户信息
	 * @param token
	 * @return
	 */
	@GetMapping("/validate")
	public Object validate(String token) {
		String user = this.jedisClient.get(SSOConfig.REDIS_KEY_SSO_TOKEN_KEY + ":" + token);
		if(null != user) { //如果Token有效则重设过期时间
			this.jedisClient.expire(SSOConfig.REDIS_KEY_SSO_TOKEN_KEY + ":" + token, SSOConfig.TIMEOUT);
		}
		return JSON.parseObject(user, SSOUser.class);
	}


}
